/*
 * fuse.c
 *
 *  Created on: 02/12/2011
 *      Author: utn_so
 */


#include "./includes/FuncionesArchConfig.h"
#include "./includes/funcionesConsola.h"
#include "../../Commons/src/includes/BibliotecasGenerales.h"
#include "includes/utilesConexion.h"
#include "./includes/funcionesUtiles.h"
#include "./includes/funcionesFat.h"
#include "./includes/estructuraFAT.h"
#include "./includes/variablesGlobales.h"
#include "./includes/utils.h"
#include "./includes/cacheArchivos.h"
#include <fuse.h>




int fuse_open(const char *path, struct fuse_file_info *fi){
	int32_t sizeArchivo,esArchivo,elementos;
	if((elementos=pathValido(path,listaRaiz,&sizeArchivo,&esArchivo)) == -1){
		return -ENOENT;
	}
	return 0;
}

int fuse_read(const char *path, char *buf,size_t size, off_t offset,struct fuse_file_info *fi){

	 return leerArchivo(path,listaRaiz,bootSector,tablaFat,buf,offset,size);
}

int fuse_write(const char *path, const char *buf, size_t size, off_t offset,struct fuse_file_info *fi){

	return escribirArchivo(path ,listaRaiz,bootSector,tablaFat,buf,offset,size);
}

int fuse_flush(const char *path, struct fuse_file_info *fi){
	ptrCacheArchivo cacheArchivo;
	cacheArchivo = listaCacheArchivos;
	while(cacheArchivo != NULL){
		flushDelArchivo(&cacheArchivo);
		cacheArchivo = cacheArchivo->ptrSigArchivo;
	}
	return 0;
}

int fuse_release(const char *path, struct fuse_file_info *fi){
	ptrCacheArchivo cacheArchivo;
	cacheArchivo=buscarArchivoEnCache(path,listaCacheArchivos);
	if(cacheArchivo == NULL){
		return -ENOENT;
	}
	flushDelArchivo(&cacheArchivo);
	return 0;
}

int fuse_truncate(const char *path, off_t newsize){
	int32_t ret=0,primerClusterSiEsCero;
	ret=cambiarTamanio(bootSector,path,newsize,listaRaiz,tablaFat,&primerClusterSiEsCero);
	if (ret == -1){
		return -ENOENT;
	}
	return 0;
}

int fuse_unlink(const char * path){

	return removerArchivo(path,tablaFat);
}

int fuse_mkdir(const char *path, mode_t mode){

	crearDirectorioFat32(path);
	return 0;
}
int fuse_create(const char *path,mode_t mode,struct fuse_file_info *fi){
	crearArchivoFat32(path);
	return 0;
}


int fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi){
	(void) offset;
	(void) fi;
	int32_t tamArc;
	int32_t esArchivo,cant;
	ptrListaNom_t listaNombres=NULL,ptr;
	if(memcmp(path, "/",strlen(path)) != 0){
		if((cant=pathValido(path,listaRaiz,&tamArc,&esArchivo)) == -1 ){
			return -ENOENT;
		}

		if(esArchivo){
			return -ENOENT;
		}
		else{
			mostrarListadoFat32(path,&listaNombres,listaRaiz);
			ptr=listaNombres;
			while(ptr!=NULL){
				filler(buf,ptr->nombre,NULL,0);
				ptr=ptr->siguiente;
			}
			return 0;
		}
	}
	filler(buf, ".", NULL, 0);
	filler(buf, "..", NULL, 0);
	mostrarListadoFat32(path,&listaNombres,listaRaiz);
	ptr=listaNombres;
	while(ptr!=NULL){
		filler(buf,ptr->nombre,NULL,0);
		ptr=ptr->siguiente;
	}

	return 0;
}

int fuse_rmdir(const char * path){
	int16_t ret=0;

	ret=eliminarDirectorioFat32(path);

	if(ret == -1){
		return -ENOENT;
	}
	return 0;
}


int fuse_getattr(const char *path, struct stat *stbuf){

	int32_t cantElem,sizeArchivo,esArchivo;


	memset(stbuf, 0, sizeof(struct stat));

	if (strcmp(path, "/") == 0) {
		stbuf->st_mode = S_IFDIR | 0755;
		cantElem=elementosListaRaiz(listaRaiz);
		stbuf->st_nlink = cantElem;
		return 0;
	}

	if( (cantElem=pathValido(path,listaRaiz,&sizeArchivo,&esArchivo)) == -1){
		return -ENOENT;
	}

	if(esArchivo==1){
		stbuf->st_mode = S_IFREG | S_IREAD | S_IRGRP | S_IROTH |S_IWRITE | S_IWGRP | S_IWOTH;
		stbuf->st_size =sizeArchivo;
		stbuf->st_nlink = 1;
		stbuf->st_size =sizeArchivo;
		return 0;
	}
	else{ /*es un directorio*/
		stbuf->st_mode = S_IFDIR | S_IREAD | S_IRGRP | S_IROTH ;
		stbuf->st_nlink = cantElem;
		return 0;
	}
}

int fuse_rename(const char * path, const char * newpath){
	char *nuevoNombre;

	nuevoNombre=sacaUltimoParametroDePath(newpath);
	cambiarNombreFat32(path,nuevoNombre);
	free(nuevoNombre);
	return 0;
}

